package com.API.dal.providers;

import com.API.dal.entities.*;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Repository
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public class EquipmentsProviderImp implements EquipmentsProvider{

    @Autowired
    SessionFactory sessionFactory;

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void addEquipment(Equipments equipment, String equipment_type) {
        Session session = sessionFactory.getCurrentSession();
        equipment.setEquipmentsTypes(getEquipmentTypeByName(equipment_type));
        session.save(equipment);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void addEquipment(Equipments equipment, EquipmentsTypes equipment_type) {
        Session session = sessionFactory.getCurrentSession();
        equipment.setEquipmentsTypes(equipment_type);
        session.save(equipment);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void updateEquipment(Equipments equipment) {
        Session session = sessionFactory.getCurrentSession();
        session.update(equipment);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void addEquipmentType(EquipmentsTypes equipment_type) {
        Session session = sessionFactory.getCurrentSession();
        session.save(equipment_type);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void updateEquipmentType(EquipmentsTypes equipment_type) {
        Session session = sessionFactory.getCurrentSession();
        session.update(equipment_type);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void addMaterial(Equipments equipments) {
        Session session = sessionFactory.getCurrentSession();
        equipments.setStatus("Неизвестно");
        session.save(equipments);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void addTool(Equipments equipments) {
        Session session = sessionFactory.getCurrentSession();
        session.save(equipments);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void addMechanism(Equipments equipments) {
        Session session = sessionFactory.getCurrentSession();
        session.save(equipments);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void addMaterialProject(EquipmentsProjects equipmentsProjects) {
        Session session = sessionFactory.getCurrentSession();
        session.save(equipmentsProjects);
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public void addEquipmentCost(EquipmentCosts equipmentCosts) {
        Session session = sessionFactory.getCurrentSession();
        session.save(equipmentCosts);
    }

    @Override
    @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
    public List<EquipmentsTypes> getEquipmentsTypes() {
        List<EquipmentsTypes> equipmentsTypesListList;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from EquipmentsTypes et");
        equipmentsTypesListList = query.list();
        return equipmentsTypesListList;
    }

    @Override
    @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
    public EquipmentsTypes getEquipmentTypeByName(String name) {
        EquipmentsTypes equipmentsTypes;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from EquipmentsTypes et  where et.name = " + name);
        equipmentsTypes = (EquipmentsTypes) query.uniqueResult();
        return equipmentsTypes;
    }

    @Override
    @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
    public List<Equipments> getEquipments() {
        List<Equipments> equipmentsList;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from Equipments e ");
        equipmentsList = query.list();
        for (Equipments eq: equipmentsList){
            query = session.createQuery("from Units u where u.id = " + eq.getUnits().getId());
            eq.setUnits((Units) query.uniqueResult());
            query = session.createQuery("from EquipmentsTypes et where et.id = " + eq.getEquipmentsTypes().getId());
            eq.setEquipmentsTypes((EquipmentsTypes) query.uniqueResult());
        }
        return equipmentsList;
    }

    @Override
    @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
    public List<Equipments> getMaterials() {
        List<Equipments> equipmentsList;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from Equipments e  where e.equipmentsTypes.id in " +
                "(select et.id from EquipmentsTypes et where et.name =  'Материалы' )");
        equipmentsList = query.list();
        return equipmentsList;
    }

    @Override
    @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
    public List<Equipments> getTools() {
        List<Equipments> equipmentsList;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from Equipments e  where e.equipmentsTypes.id in " +
                "(select et.id from EquipmentsTypes et where et.name =  'Инструменты' )");
        equipmentsList = query.list();
        return equipmentsList;
    }

    @Override
    @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
    public List<Equipments> getMechanisms() {
        List<Equipments> equipmentsList;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from Equipments e  where e.equipmentsTypes.id in " +
                "(select et.id from EquipmentsTypes et where et.name =  'Техника' )");
        equipmentsList = query.list();
        return equipmentsList;
    }

    @Override
    @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
    public Equipments getEquipmentById(int id) {
        Equipments equipments;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from Equipments e  where e.id = " + id);
        equipments = (Equipments) query.uniqueResult();
        return equipments;
    }

    @Override
    @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
    public Equipments getEquipmentByName(String name) {
        Equipments equipments;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from Equipments e  where e.name = '" + name + "'");
        equipments = (Equipments) query.uniqueResult();
        return equipments;
    }

    @Override
    @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
    public List<Equipments> getEquipmentsByType(String type_name) {
        List<Equipments> equipmentsList;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from Equipments e  where e.equipmentsTypes.id in " +
                "(select et.id from EquipmentsTypes et where et.name =  " + type_name + " )");
        equipmentsList = query.list();
        return equipmentsList;
    }

    @Override
    @Transactional(readOnly=true,propagation= Propagation.SUPPORTS)
    public List<Equipments> getEquipmentsByType(EquipmentsTypes type) {
        List<Equipments> equipmentsList;
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Equipments.class);
        Query query = session.createQuery("from Equipments e  where e.equipmentsTypes.id in " +
                "(select et.id from EquipmentsTypes et where et.id =  " + type.getId() + " )");
        equipmentsList = query.list();
        return equipmentsList;
    }

    @Override
    @Transactional(readOnly=true,propagation= Propagation.SUPPORTS)
    public EquipmentsTypes getEquipmentType(int equipment_id) {
        EquipmentsTypes et;
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("select et from EquipmentsTypes et, Equipments ec where et.id = ec.equipmentsTypes.id " +
                " and ec.id = " + equipment_id);
        et = (EquipmentsTypes) query.uniqueResult();
        return et;
    }

    @Override
    @Transactional(readOnly=true,propagation= Propagation.SUPPORTS)
    public Units getEquipmentUnit(int equipment_id) {
        Units un;
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("select u from Units u, Equipments ec where u.id = ec.units.id " +
                " and ec.id = " + equipment_id);
        un = (Units) query.uniqueResult();
        return un;
    }

    @Override
    @Transactional(readOnly=true,propagation= Propagation.SUPPORTS)
    public Units getEquipmentUnit(String unit_name) {
        Units un;
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("from Units u where u.name = '" + unit_name + "'");
        un = (Units) query.uniqueResult();
        return un;
    }

    @Override
    @Transactional(readOnly=true,propagation= Propagation.SUPPORTS)
    public EquipmentsTypes getEquipmentType(String equipment_name) {
        EquipmentsTypes et;
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("from EquipmentsTypes et where et.name = '" + equipment_name + "'");
        et = (EquipmentsTypes) query.uniqueResult();
        return et;
    }

    @Override
    @Transactional(readOnly=true,propagation= Propagation.SUPPORTS)
    public List<Units> getUnits() {
        List<Units> unitsList;
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("from Units u");
        unitsList = query.list();
        return unitsList;
    }
}
